package com.z.system.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.z.system.dto.RoleDTO;
import com.z.system.model.Role;
import com.z.system.service.RoleService;
import com.z.system.utils.PageResult;
import com.z.system.utils.R;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 角色控制器
 */
@RestController
@RequestMapping("/api/role")
@Tag(name = "角色管理", description = "角色相关接口")
public class RoleController {

    @Autowired
    private RoleService roleService;

    /**
     * 获取角色列表
     */
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:view')")
    @Operation(summary = "获取角色列表", description = "分页获取角色列表，支持按条件筛选", responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "角色列表", content = @Content(schema = @Schema(implementation = PageResult.class))))
    public R<PageResult<RoleDTO>> getRoles(
            @Parameter(description = "页码，默认0", example = "0") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页数量，默认10", example = "10") @RequestParam(defaultValue = "10") int size,
            @Parameter(description = "角色名称") @RequestParam(required = false) String roleName,
            @Parameter(description = "角色编码") @RequestParam(required = false) String roleCode) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("createTime").descending());
        Map<String, Object> params = new HashMap<>();
        params.put("name", roleName);
        params.put("code", roleCode);
        // 直接从数据库查询获取RoleDTO列表，避免额外的实体到DTO转换，并传递搜索参数
        Page<RoleDTO> roleDTOPage = roleService.getRoleDTOs(pageable, params);

        PageResult<RoleDTO> result = new PageResult<>(
                roleDTOPage.getContent(),
                roleDTOPage.getNumber() + 1,
                roleDTOPage.getSize(),
                roleDTOPage.getTotalElements());

        return R.success("请求成功", result);
    }

    /**
     * 获取所有角色（不分页）
     */
    @GetMapping("/all")
    @Operation(summary = "获取所有角色", description = "获取所有角色列表，不分页", responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "角色列表", content = @Content(schema = @Schema(implementation = List.class))))
    public List<Role> getAllRoles() {
        return roleService.getAllRoles();
    }

    /**
     * 获取角色详情
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('sys:role:view')")
    @Operation(summary = "获取角色详情", description = "根据角色ID获取角色详情", responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "角色详情", content = @Content(schema = @Schema(implementation = Role.class))))
    public Role getRole(@Parameter(description = "角色ID", required = true) @PathVariable UUID id) {
        return roleService.getRoleById(id);
    }

    /**
     * 创建角色
     */
    @PostMapping("/add")
    @PreAuthorize("hasAuthority('sys:role:create')")
    @Operation(summary = "创建角色", description = "创建新的角色", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = RoleDTO.class))), responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功"))
    public R createRole(@Parameter(description = "角色信息", required = true) @RequestBody RoleDTO roleDTO) {
        Role role = roleDTO.toRole();
        roleService.saveRole(role);
        return R.success("创建成功", role.getId().toString());
    }

    /**
     * 更新角色
     */
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:role:update')")
    @Operation(summary = "更新角色", description = "更新角色信息", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = RoleDTO.class))), responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功"))
    public R updateRole(@Parameter(description = "角色信息", required = true) @RequestBody RoleDTO roleDTO) {
        Role role = roleDTO.toRole();
        roleService.updateRole(role);
        return R.success("更新成功", "");
    }

    /**
     * 删除角色
     */
    @PostMapping("/delete/{id}")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    @Operation(summary = "删除角色", description = "根据角色ID删除角色", responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功"))
    public R deleteRole(@Parameter(description = "角色ID", required = true) @PathVariable UUID id) {
        roleService.deleteRole(id);
        return R.success("删除成功", id.toString());
    }

    /**
     * 批量删除角色
     */
    @PostMapping("/delete/batch")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    @Operation(summary = "批量删除角色", description = "批量删除多个角色", requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(content = @Content(schema = @Schema(implementation = Set.class))), responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功"))
    public R deleteRoles(@Parameter(description = "角色ID集合", required = true) @RequestBody Set<UUID> ids) {
        roleService.deleteRoles(ids);
        return R.success("删除成功", "");
    }

    /**
     * 分配角色权限
     */
    @PostMapping("/{id}/permissions")
    @PreAuthorize("hasAuthority('sys:role:update')")
    @Operation(summary = "分配角色权限", description = "为角色分配权限")
    public R<String> assignPermissions(@Parameter(description = "角色ID", required = true) @PathVariable UUID id,
            @Parameter(description = "权限ID集合", required = true) @RequestBody Set<String> permissionIds) {
        roleService.assignPermissions(id, permissionIds);
        return R.success("分配成功", "");
    }

    /**
     * 获取角色权限ID集合
     */
    @GetMapping("/{id}/permissions")
    @PreAuthorize("hasAuthority('sys:role:view')")
    @Operation(summary = "获取角色权限ID集合", description = "获取指定角色拥有的权限ID集合", responses = @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "权限ID集合", content = @Content(schema = @Schema(implementation = Set.class))))
    public R<Set<UUID>> getRolePermissions(@Parameter(description = "角色ID", required = true) @PathVariable UUID id) {
        return R.success("获取成功", roleService.getRolePermissionIds(id));
    }
}